/**
 * 使用对象来存储收集响应式依赖
 * 对于对象的依赖管理
 * WeakMap---- obj==>map
 * map----- key==>Depend实例
 */
let activeReactiveFn = null

class Depend {
  constructor() {
    this.reactiveFns = new Set()
  }
  
  //添加依赖
  addDepend(fn) {
    this.reactiveFns.add(fn)
  }
  
  depend() {
    if (activeReactiveFn) {
      this.reactiveFns.add(activeReactiveFn)
    }
  }
  
  //遍历执行依赖
  notify() {
    this.reactiveFns.forEach(fn => fn())
  }
}

function watchFn(fn) {
  activeReactiveFn = fn
  //这里要执行一次，才能正确的收集依赖
  fn()
  activeReactiveFn = null
}

//获取obj-key对应的depend
const targetMap = new WeakMap()

function getDepends(obj, key) {
  //根据obj获取响应的map对象
  let objMap = targetMap.get(obj)
  if (!objMap) {
    //说明针对obj对象的依赖还未收集,为其新建一个map
    objMap = new Map
    targetMap.set(obj, objMap)
  }
  //根据key获取depend对象
  let depend = objMap.get(key)
  if (!depend) {
    depend = new Depend()
    objMap.set(key, depend)
  }
  return depend
}

const
  obj = {
    name: 'l',
    age: 18
  }


//监测obj
const objProxy = new Proxy(obj, {
  get(target, key, receiver) {
    console.log('===get===')
    //收集依赖
    const dep = getDepends(target, key)
    dep.depend()
    return Reflect.get(target, key, receiver)
  },
  set(target, key, value, receiver) {
    console.log('===set===')
    Reflect.set(target, key, value, receiver)
    const depend = getDepends(target, key)
    depend.notify()
  }
})


watchFn(function () {
  console.log(objProxy.name, '------')
  console.log(objProxy.name, '++++++')
})
watchFn(function () {
  console.log('my name is ' + objProxy.name)
})
watchFn(function () {
  console.log(objProxy.age)
})

console.log(getDepends(obj, 'name'))
console.log(getDepends(obj, 'age'))

objProxy.age = 190
